package com.gzhryc.shared_device.oem.micro.queue.times;

import java.util.Date;
import java.util.List;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.gzhryc.common.DateTools;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.kafka.JFKafkaProducer;
import com.gzhryc.common.kafka.KafkaProducerFactory;
import com.gzhryc.common.kafka.models.KafkaMessage;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.shared_device.base.enums.EOperatorType;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.cdcz.code.dao.db.CDCZOrder;
import com.gzhryc.shared_device.cdcz.code.services.CDCZOrderService;
import com.gzhryc.shared_device.cdcz.core.ICDCZNetworkService;
import com.gzhryc.shared_device.common.BusyThreadPool;
import com.gzhryc.shared_device.oem.code.HttpNetworkServiceUtils;
import com.gzhryc.shared_device.oem.code.KafkaEventConstants;
import com.gzhryc.shared_device.oem.code.PayServiceFactory;
import com.gzhryc.shared_device.oem.code.business.EBusinessType;
import com.gzhryc.shared_device.oem.code.device.EDeviceFunCode;
import com.gzhryc.shared_device.oem.code.member.dao.db.MemberBusinessOrder;
import com.gzhryc.shared_device.oem.code.member.dao.enums.MemberBusinessOrderEnum;
import com.gzhryc.shared_device.oem.code.member.services.MemberBusinessOrderService;
import com.gzhryc.shared_device.oem.code.member.services.dto.MemberBusinessOrderSearch;
import com.gzhryc.shared_device.oem.code.order.RedisCacheManager;
import com.gzhryc.shared_device.oem.code.order.event.OrderCancelEvent;
import com.gzhryc.shared_device.oem.code.order.event.OrderFinishEvent;
import com.gzhryc.shared_device.oem.code.place.services.PlaceBusinessConfigService;
import com.gzhryc.shared_device.oem.code.profit.service.BusinessOrderService;
import com.gzhryc.shared_device.oem.micro.queue.MicroConstants;
import com.gzhryc.shared_device.oem.micro.queue.work.PCLFinishCheckRunnable;

public class Every5HourCheckJob implements Job {

    static Logger log = Logger.getLogger(Every5HourCheckJob.class);

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        log.info("设备订单完成检查，每5个小时检查一次");

        OperateInfo operateInfo = new OperateInfo(MicroConstants.PROGRAM_TYPE, MicroConstants.PROGRAM_TYPE_NAME);
        operateInfo.setOperator(EOperatorType.System.index(), "每5小时定时检查程序");

        BusyThreadPool.self().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    MemberBusinessOrderSearch search = new MemberBusinessOrderSearch();
                    search.setState(MemberBusinessOrderEnum.State.Working.index());
                    Integer pageNo = 1;
                    Integer pageLimit = 200;

                    OperateInfo operateInfo = new OperateInfo(MicroConstants.PROGRAM_TYPE, MicroConstants.PROGRAM_TYPE_NAME);
                    operateInfo.setOperator(EOperatorType.System.index(), "5小时定时检查程序");

                    //TODO 当年订单
                    Date currentDate = new Date();
                    List<MemberBusinessOrder> businessOrderList = MemberBusinessOrderService.self(currentDate).findBySearch(search, pageNo, pageLimit);
                    while (businessOrderList != null && businessOrderList.size() > 0) {
                        for (MemberBusinessOrder businessOrder : businessOrderList) {
                            if(EBusinessType.CDCZ.index().equals(businessOrder.getBusinessType())) {
                                CDCZOrder deviceOrder = CDCZOrderService.self(businessOrder.getCreateDate()).getByTradeNo(businessOrder.getTradeNo());
                                if(deviceOrder != null){
                                    if(deviceOrder.getEndDate() == null){
                                        Long times = DateTools.differenceMinute(deviceOrder.getCreateDate(),new Date());
                                        if(times > 13){  //13分钟
                                            //清理缓存，避免定时器重复处理
                                            RedisCacheManager.removeWorkingCDCZDeviceOrder(deviceOrder.getTradeNo());

                                            ICDCZNetworkService networkService = HttpNetworkServiceUtils.getCDCZNetworkService(deviceOrder.getIotId());
                                            boolean synCancel = false;
                                            Date cancelDate = new Date();
                                            Long incomeMoney = deviceOrder.getIncomeMoney();
                                            operateInfo.setOperateNote("无结束时间订单，撤销处理");
                                            Integer result = CDCZOrderService.self(deviceOrder.getCreateDate()).cancel(deviceOrder, PayServiceFactory.self(), networkService, operateInfo);
                                            if (result > 0) {
                                                synCancel = true;
                                            } else {
                                                log.error("撤销充电插座订单失败，订单信息：{{0:json}}", deviceOrder);
                                            }

                                            if(synCancel){
                                                deviceOrder = CDCZOrderService.self(deviceOrder.getCreateDate()).getByTradeNo(deviceOrder.getTradeNo());
                                                MemberBusinessOrderService.self(deviceOrder.getCreateDate()).cancel(deviceOrder.getTradeNo()
                                                        ,deviceOrder.getMoney(),deviceOrder.getPayMoney(),deviceOrder.getWalletMoney());
                                                BusinessOrderService.self(deviceOrder.getCreateDate()).cancel(deviceOrder.getTradeNo(),cancelDate);
                                                JFKafkaProducer producer = KafkaProducerFactory.self().getProducer();
                                                if (producer != null) {
                                                    OrderCancelEvent event = new OrderCancelEvent(EDeviceFunCode.CDCZ.index(),deviceOrder.getTradeNo()
                                                            ,deviceOrder.getCreateDate(),incomeMoney,cancelDate);
                                                    KafkaMessage kafkaMessage = new KafkaMessage(KafkaEventConstants.TOPIC_Order,
                                                            KafkaEventConstants.KEY_OrderCancel, JsonTools.toJson(event));
                                                    producer.send(kafkaMessage);
                                                }
                                            }
                                        }
                                    }else {
                                        Long times = DateTools.differenceMinute(new Date(), deviceOrder.getEndDate());
                                        if (times <= 0) {
                                            //清理缓存，避免定时器重复处理
                                            RedisCacheManager.removeWorkingCDCZDeviceOrder(deviceOrder.getTradeNo());
                                            Long payMoney = PlaceBusinessConfigService.self().getCDCZPayMoney(deviceOrder.getPlaceId(),deviceOrder.getMaxUsePower());
                                            ICDCZNetworkService networkService = HttpNetworkServiceUtils.getCDCZNetworkService(deviceOrder.getIotId());
                                            operateInfo.setOperateNote("订单到时完成");
                                            if(CDCZOrderService.self(deviceOrder.getCreateDate()).timesFillToFinish(deviceOrder, payMoney,networkService, operateInfo)){
                                                deviceOrder = CDCZOrderService.self(deviceOrder.getCreateDate()).getByTradeNo(deviceOrder.getTradeNo());
                                                MemberBusinessOrderService.self(deviceOrder.getCreateDate()).finish(deviceOrder.getTradeNo(), deviceOrder.getMoney(), deviceOrder.getPayMoney()
                                                        ,deviceOrder.getWalletMoney(),operateInfo);
                                                JFKafkaProducer producer = KafkaProducerFactory.self().getProducer();
                                                if (producer != null) {
                                                    OrderFinishEvent event = new OrderFinishEvent(EBusinessType.CDCZ.index(), deviceOrder.getTradeNo(),deviceOrder.getCreateDate(),operateInfo);
                                                    KafkaMessage kafkaMessage = new KafkaMessage(KafkaEventConstants.TOPIC_Order, KafkaEventConstants.KEY_OrderFinish, JsonTools.toJson(event));
                                                    producer.send(kafkaMessage);
                                                }
                                            }else{
                                                log.error("完成充电插座订单失败，订单信息：{{0:json}}", deviceOrder);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        pageNo = pageNo + 1;
                        businessOrderList = MemberBusinessOrderService.self(currentDate).findBySearch(search, pageNo, pageLimit);
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
        });

        BusyThreadPool.self().execute(new PCLFinishCheckRunnable(operateInfo));
    }
}
